/*
 * atomic-x86.h
 *
 *  Created on: 2011-8-4
 *      Author: gexiao
 */

#ifndef ATOMIC_X86_H_
#define ATOMIC_X86_H_
#include <stdint.h>
#include "../ItbInlines.h"

ITB_INLINE void android_compiler_barrier(void) {
	__asm__ __volatile__ ("" : : : "memory");
}

#if ANDROID_SMP == 0
ITB_INLINE void android_memory_barrier(void) {
	android_compiler_barrier();
}
#else
ITB_INLINE void android_memory_barrier(void)
{
	__asm__ __volatile__ ("mfence" : : : "memory");
}
#endif

ITB_INLINE void android_atomic_acquire_store(int32_t value,
		volatile int32_t *ptr) {
	*ptr = value;
	android_memory_barrier();
}

ITB_INLINE void android_atomic_release_store(int32_t value,
		volatile int32_t *ptr) {
	android_compiler_barrier();
	*ptr = value;
}
ITB_INLINE int android_atomic_cas(int32_t old_value, int32_t new_value,
		volatile int32_t *ptr) {
	int32_t prev;
	__asm__ __volatile__ ("lock; cmpxchgl %1, %2"
			: "=a" (prev)
			: "q" (new_value), "m" (*ptr), "0" (old_value)
			: "memory");
	return prev != old_value;
}

ITB_INLINE int android_atomic_acquire_cas(int32_t old_value, int32_t new_value,
		volatile int32_t *ptr) {
	/* Loads are not reordered with other loads. */
	return android_atomic_cas(old_value, new_value, ptr);
}

ITB_INLINE int android_atomic_release_cas(int32_t old_value, int32_t new_value,
		volatile int32_t *ptr) {
	return android_atomic_cas(old_value, new_value, ptr);
}

#endif /* ATOMIC_X86_H_ */
